using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Crm.Domain.TestUtil;
using TestUtil.Equality;

namespace Crm.Domain.Tests
{
    [TestFixture]
    public class NameTests
    {
        #region Tests

        [Test]
        public void CanCreate()
        {
            Name name = new Name(CustomerCommonTestValues.FirstName, CustomerCommonTestValues.LastName);

            Assert.AreEqual(name.FirstName, CustomerCommonTestValues.FirstName);
            Assert.AreEqual(name.LastName, CustomerCommonTestValues.LastName);
        }

        [Test]
        public void ToStringTest()
        {
            Name name = new Name("Frank", "Jones");

            Assert.AreEqual("Frank Jones", name.ToString());
        }
		 
	    #endregion

        # region Tests - Expected Exceptions

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void FirstNameCannotBeNull()
        {
            new Name(null, CustomerCommonTestValues.LastName);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void LastNameCannotBeNull()
        {
            new Name(CustomerCommonTestValues.FirstName, null);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void FirstNameCannotBeEmpty()
        {
            new Name(String.Empty, CustomerCommonTestValues.LastName);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void LastNameCannotBeEmpty()
        {
            new Name(CustomerCommonTestValues.FirstName, String.Empty);
        }

        # endregion

        # region Tests - Equality

        /// <summary>
        /// Since <see cref="Name"/> is a value object it must support equality being based on its values, this class tests that
        /// this is working.
        /// </summary>
        [Test]
        public void NameEqualityBehavesCorrectly()
        {
            CreateTestObjectCallback<Name> createFirstName = delegate { return new Name("FirstName", "SecondName"); };
            CreateTestObjectCallback<Name> createSecondName = delegate { return new Name("OtherFirstName", "OtherSecondName"); };

            ReferenceTypeValueObjectEqualityTestHelper<Name> helper = 
                                    new ReferenceTypeValueObjectEqualityTestHelper<Name>(createFirstName, createSecondName);

            helper.PerformTest();
        }

        # endregion
    }
}
